<script setup lang="ts">
import { ComponentEnum } from '@/enum/ComponentEnum.ts'
import {  BusinessEnum } from '@/enum/ApiEnum.ts'
import type { FormInst, FormItemRule, FormRules } from 'naive-ui'
import type { SelectOption, TreeSelectOption, CascaderOption } from 'naive-ui'

import { SaveConfig } from '@/components/type/SaveConfig'
import { ObjectUtil } from '@/util/ObjectUtil'
import { PeaceColumn } from '@/components/type/PeaceColumn'
import Formz from '@/infrastructure/PeaceDataTable/component/Formz/index.vue'

// 组件属性定义
const props = withDefaults(defineProps<{
  config: SaveConfig,
  // 模态框是否显示
  show: boolean,
}>(),{
  config: () => {
    return {
      title: "保存",
      type: BusinessEnum.ADD,
      columns: [],
    }
  },
  show: false,
})

// 组件事件
const emit = defineEmits<{
  // 关闭模态框
  (e: 'update:show', value: boolean): void,
  // 提交表单
  (e: 'submit', value: Record<string, any>): void,
  // 取消操作
  (e: 'cancel'): void
}>()

// 表单实例
const formRef = ref<FormInst | null>(null)
// 表单数据
const model = ref<Record<string, any>>({})
// 表单规则
const rules = ref<FormRules>({})

// 模态框标题
const modalTitle = computed(() => {
  if (props.config.title) return props.config.title

  switch (props.config.type) {
    case BusinessEnum.ADD:
      return '新增'
    case BusinessEnum.UPDATE:
      return '编辑'
    case BusinessEnum.COPY:
      return '复制'
    default:
      return '操作'
  }
})

// 过滤出可编辑的列
const editableColumns = computed(() => {
  return props.config.columns.filter(item=>{
    if (item.hasOwnProperty("type")){
      return false
    }
    if (item.key === "tableRowAction"){
      return false
    }
    if (props.config.type === BusinessEnum.ADD){
      if (ObjectUtil.isNotNullAndUndefined(item.saveConfig?.peaceAddable)){
        return item.saveConfig.peaceAddable
      }
    }
    if (props.config.type === BusinessEnum.UPDATE){
      if (ObjectUtil.isNotNullAndUndefined(item.saveConfig?.peaceUpdatable)){
        return item.saveConfig.peaceUpdatable
      }
    }
    if (props.config.type === BusinessEnum.COPY){
      if (ObjectUtil.isNotNullAndUndefined(item.saveConfig?.peaceCopyable)){
        return item.saveConfig.peaceCopyable
      }
    }
    if (ObjectUtil.isNotNullAndUndefined(item.saveConfig?.peaceEditable)){
      return item.saveConfig.peaceEditable
    }
    return true
  })
})
console.log(editableColumns.value,"editableColumns")
// 初始化表单数据和规则
const initForm = () => {
  const newModel: Record<string, any> = {}
  const newRules: FormRules = {}

  editableColumns.value.forEach((col:PeaceColumn) => {
    const key = col.key as string

    // 初始化表单数据
    if (props.config.type === BusinessEnum.ADD) {
      newModel[key] = null
    } else if (props.config.formData && (props.config.type === BusinessEnum.UPDATE || props.config.type === BusinessEnum.COPY)) {
      newModel[key] = props.config.formData[key]
    }

    // 初始化表单规则
    if (col.saveConfig) {
      const rule: FormItemRule = {
        required: col.saveConfig.required !== false,
        trigger: ['blur', 'input', 'change'],
        message: `${col?.title}不能为空`
      }

      // 添加自定义验证器
      if (col.saveConfig.validator) {
        rule.validator = (rule, value) => {
          if (col.saveConfig?.validator && !col.saveConfig.validator(value)) {
            return new Error('验证失败')
          }
          return true
        }
      } else {
        // 为不同组件类型添加默认验证器
        // if (col.peaceRender || col.componentEnum === ComponentEnum.TREE_SELECT || col.componentEnum === ComponentEnum.CASCADER) {
        if (col.saveConfig?.required !== false) {
          rule.validator = (rule, value) => {
            // 对于树形选择器和级联选择器，允许任何非空值
            if (value === null || value === undefined || value === '') {
              return new Error(`请选择${col.title as string}`)
            }
            return true
          }
          // 移除类型验证
          delete rule.type
        }
      }

      // 添加长度限制
      // if (col.saveConfig.maxLength) {
      //   rule.maxLength = col.saveConfig.maxLength
      // }

      // 添加数值范围限制
      if (col.saveConfig.min !== undefined || col.saveConfig.max !== undefined) {
        if (col.componentEnum === ComponentEnum.INPUT_NUMBER) {
          if (col.saveConfig.min !== undefined) {
            rule.min = col.saveConfig.min
          }
          if (col.saveConfig.max !== undefined) {
            rule.max = col.saveConfig.max
          }
        }
      }

      newRules[key] = rule
    }
  })

  model.value = newModel
  rules.value = newRules
}

// 处理表单提交
const handleSubmit = (e: MouseEvent) => {
  e.preventDefault()
  formRef.value?.validate((errors) => {
    if (!errors) {
      emit('submit', model.value)
    }
  })
}

// 处理取消操作
const handleCancel = () => {
  emit('update:show', false)
  emit('cancel')
}

// 获取选项标签
const getOptionLabel = (option: any, labelField?: string) => {
  if (!option) return ''
  if (typeof option === 'string' || typeof option === 'number') return option

  if (labelField && option[labelField] !== undefined) {
    return option[labelField]
  }

  if (option.label !== undefined) {
    return option.label
  }

  return ''
}

// 获取选项值
const getOptionValue = (option: any, valueField?: string) => {
  if (!option) return null
  if (typeof option === 'string' || typeof option === 'number') return option

  if (valueField && option[valueField] !== undefined) {
    return option[valueField]
  }

  if (option.value !== undefined) {
    return option.value
  }

  return null
}

// 监听模态框显示状态变化
watch(() => props.show, (newVal) => {
  if (newVal) {
    initForm()
  }
}, { immediate: true })

// 监听表单数据变化
watch(() => props.config.formData, () => {
  if (props.show) {
    initForm()
  }
}, { deep: true })

// 获取渲染组件
const getRenderComponent = (col: PeaceColumn) => {
  // 新增模式
  if (props.config.type === BusinessEnum.ADD) {
    // 优先使用新增专用渲染函数
    if (col.saveConfig?.peaceAddRender) {
      return col.saveConfig.peaceAddRender(col);
    }
  }

  // 编辑模式
  if (props.config.type === BusinessEnum.UPDATE) {
    // 优先使用编辑专用渲染函数
    if (col.saveConfig?.peaceUpdateRender) {
      return col.saveConfig.peaceUpdateRender(col);
    }
  }
  // 复制模式
  if ( props.config.type === BusinessEnum.COPY) {
    // 优先使用编辑专用渲染函数
    if (col.saveConfig?.peaceCopyRender) {
      return col.saveConfig.peaceCopyRender(col);
    }
  }

  // 默认情况下使用通用渲染函数
  if (col.saveConfig?.peaceEditRender) {
    return col.saveConfig.peaceEditRender(col);
  }

  // 如果没有任何渲染函数，返回null
  return null;
}
</script>

<template>
  <n-modal
    :show="show"
    @update:show="emit('update:show', $event)"
    :title="modalTitle"
    preset="card"
    :mask-closable="false"
    :style="{width:config.dialogWidth}"
  >
    <n-form
      ref="formRef"
      :model="model"
      :rules="rules"
      label-placement="left"
      label-width="auto"
      require-mark-placement="right-hanging"
    >
      <n-grid :cols="Math.floor(editableColumns.length/8)" :x-gap="24">
        <n-grid-item v-for="col in editableColumns" :key="col.key as string">
          <n-form-item :label="col.title as string" :path="col.key as string">
            <!-- 自定义渲染 -->
            <template v-if="col.saveConfig?.peaceRender || col.saveConfig?.peaceAddRender || col.saveConfig?.peaceUpdateRender || col.saveConfig?.peaceEditRender">
              <component
                :is="getRenderComponent(col)"
                v-model:value="model[col.key as string]"
              />
            </template>
            <!-- 普通输入框 -->
            <template v-else-if="col.componentEnum === ComponentEnum.INPUT">
              <n-input
                v-model:value="model[col.key as string]"
                :placeholder="`请输入${col.title as string}`"
              />
            </template>

            <!-- 数字输入框 -->
            <template v-else-if="col.componentEnum === ComponentEnum.INPUT_NUMBER">
              <n-input-number
                v-model:value="model[col.key as string]"
                :placeholder="`请输入${col.title as string}`"
                :min="col.saveConfig?.min"
                :max="col.saveConfig?.max"
                style="width: 100%"
              />
            </template>

            <!-- 下拉选择框 -->
            <template v-else-if="col.componentEnum === ComponentEnum.SELECT">
              <n-select
                v-model:value="model[col.key as string]"
                :options="(col.saveConfig?.optionConfig?.peaceOption || col.optionConfig?.peaceOption) as Array<SelectOption>"
                :label-field="col.saveConfig?.optionConfig?.peaceLabelField || col.optionConfig?.peaceLabelField || 'label'"
                :value-field="col.saveConfig?.optionConfig?.peaceValueField || col.optionConfig?.peaceValueField || 'value'"
                :placeholder="`请选择${col.title as string}`"
                style="width: 100%"
              />
            </template>

            <!-- 树形选择框 -->
            <template v-else-if="col.componentEnum === ComponentEnum.TREE_SELECT">
              <n-tree-select
                v-model:value="model[col.key as string]"
                :options="(col.saveConfig?.optionConfig?.peaceOption || col.optionConfig?.peaceOption) as Array<TreeSelectOption>"
                :label-field="col.saveConfig?.optionConfig?.peaceLabelField || col.optionConfig?.peaceLabelField || 'label'"
                :key-field="col.saveConfig?.optionConfig?.peaceValueField || col.optionConfig?.peaceValueField || 'value'"
                :children-field="col.saveConfig?.optionConfig?.peaceOptionChildField || col.optionConfig?.peaceOptionChildField || 'children'"
                :placeholder="`请选择${col.title as string}`"
                style="width: 100%"
              />
            </template>

            <!-- 日期选择器 -->
            <template v-else-if="col.componentEnum === ComponentEnum.DATE">
              <n-date-picker
                v-model:value="model[col.key as string]"
                type="date"
                :placeholder="`请选择${col.title as string}`"
                style="width: 100%"
              />
            </template>

            <!-- 级联选择器 -->
            <template v-else-if="col.componentEnum === ComponentEnum.CASCADER">
              <n-cascader
                v-model:value="model[col.key as string]"
                :options="(col.saveConfig?.optionConfig?.peaceOption || col.optionConfig?.peaceOption) as Array<CascaderOption>"
                :label-field="col.saveConfig?.optionConfig?.peaceLabelField || col.optionConfig?.peaceLabelField || 'label'"
                :value-field="col.saveConfig?.optionConfig?.peaceValueField || col.optionConfig?.peaceValueField || 'value'"
                :children-field="col.saveConfig?.optionConfig?.peaceOptionChildField || col.optionConfig?.peaceOptionChildField || 'children'"
                :placeholder="`请选择${col.title as string}`"
                style="width: 100%"
              />
            </template>

            <!-- 单选框组 -->
            <template v-else-if="col.componentEnum === ComponentEnum.RADIO">
              <n-radio-group v-model:value="model[col.key as string]">
                <n-space>
                  <n-radio
                    v-for="(option, index) in (col.saveConfig?.optionConfig?.peaceOption || col.optionConfig?.peaceOption)"
                    :key="index"
                    :value="getOptionValue(option, col.saveConfig?.optionConfig?.peaceValueField || col.optionConfig?.peaceValueField)"
                  >
                    {{ getOptionLabel(option, col.saveConfig?.optionConfig?.peaceLabelField || col.optionConfig?.peaceLabelField) }}
                  </n-radio>
                </n-space>
              </n-radio-group>
            </template>

            <!-- 时间选择器 -->
            <template v-else-if="col.componentEnum === ComponentEnum.TIME_PICKER">
              <n-time-picker
                v-model:value="model[col.key as string]"
                :placeholder="`请选择${col.title as string}`"
                style="width: 100%"
              />
            </template>
          </n-form-item>
        </n-grid-item>
      </n-grid>
    </n-form>

    <template #footer>
      <n-space justify="end">
        <n-button @click="handleCancel">取消</n-button>
        <n-button type="primary" @click="handleSubmit">确定</n-button>
      </n-space>
    </template>
  </n-modal>
</template>
